<template>
  <div class="standard-table">
    <div class="alert" v-if="multipleSelect && selectedRows && selectedRows.length > 0">
      <a-alert type="info" :show-icon="true">
        <div class="message" slot="message">
          {{$t('selector.seleted')}}&nbsp;<a>{{selectedRows.length}}</a>&nbsp;{{$t('selector.records')}} <a class="clear" @click="onClear">{{$t('selector.clear')}}</a>
          <template v-for="(item, index) in needTotalList" >
            <div v-if="item.needTotal" :key="index">
              {{item.title}}{{$t('selector.total')}}&nbsp;
              <a>{{item.customRender ? item.customRender(item.total) : item.total}}</a>
            </div>
          </template>
        </div>
      </a-alert>
    </div>
    <a-table
      :scroll="(scrollX || scrollY ? {x: scrollX, y: scrollY} : {})"
      :size="size"
      :indentSize="indentSize"
      :expandRowByClick="expandRowByClick"
      :expandIconColumnIndex="expandIconColumnIndex"
      :expandIconAsCell="expandIconAsCell"
      :bordered="bordered"
      :loading="loading"
      :columns="columns"
      :rowKey="rowKey"
      :dataSource="dataSource"
      :pagination="getPagination"
      :defaultExpandedRowKeys="defaultExpandedRowKeys"
      :expandedRowKeys="expandedRowKeys"
      :expandedRowRender="expandedRowRender"
      :rowClassName="(record, index) => this.striped ? (index % 2 === 1 ? 'table-striped' : null) : null"
      :rowSelection="selectedRows ? {onSelect: onSelect, onSelectAll: onSelectAll, selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type: multipleSelect ? 'checkbox' : 'radio', columnWidth: 40 } : undefined"
      @expand="onExpand"
    >
      <template slot-scope="text, record, index" :slot="slot" v-for="slot in Object.keys($scopedSlots).filter(key => key !== 'expandedRowRender') ">
        <slot :name="slot" v-bind="{text, record, index}"></slot>
      </template>
      <template :slot="slot" v-for="slot in Object.keys($slots)">
        <slot :name="slot"></slot>
      </template>
      <template slot-scope="record, index, indent, expanded" :slot="$scopedSlots.expandedRowRender ? 'expandedRowRender' : ''">
        <slot v-bind="{record, index, indent, expanded}" :name="$scopedSlots.expandedRowRender ? 'expandedRowRender' : ''"></slot>
      </template>
      <template slot="no" slot-scope="text, record, index">
        <span>{{ (page - 1) * pageSize + ( index + 1 ) }}</span>
      </template>
    </a-table>
  </div>
</template>

<script>
export default {
  name: 'StandardTable',
  i18n: require('./i18n'),
  props: {
    size: String,
    scrollX: {
      type: [Number, String],
      // default: 'max-content'
      default: null
    },
    scrollY: {
      type: [Number, String],
      default: null
    },
    isPagination: {
      type: Boolean,
      default: true
    },
    striped: {
      type: Boolean,
      default: true
    },
    indentSize: {
      type: Number,
      default: 14
    },
    expandRowByClick: {
      type: Boolean,
      default: false
    },
    expandIconAsCell: {
      type: Boolean,
      default: true
    },
    expandIconColumnIndex: {
      type: Number,
      default: 0
    },
    page: Number,
    pageSize: Number,
    total: Number,
    bordered: {
      type: Boolean,
      default: true
    },
    multipleSelect: {
      type: Boolean,
      default: true
    },
    loading: [Boolean, Object],
    columns: Array,
    dataSource: Array,
    rowKey: {
      type: [String, Function],
      default: 'id'
    },
    selectedRows: Array,
    expandedRowKeys: Array,
    defaultExpandedRowKeys: Array,
    expandedRowRender: Function,
    onExpand: {
      type: Function,
      default: () => {}
    },
  },
  data () {
    return {
      pagination: {
        size: 'middle',
        showQuickJumper: true,
        current: 1,
        pageSize: 10,
        total: 0,
        showTotal: (total, range) => `${this.$t('pagination.the')} ${range[0]} - ${range[1]} ${this.$t('pagination.records')} / ${this.$t('pagination.total')} ${total} ${this.$t('pagination.records')}`,
        showSizeChanger: true,
        pageSizeOptions: ['10', '50', '100', '200'],
        onChange: (page, pageSize) => {
          this.pagination.current = page
          this.pagination.pageSize = pageSize
          this.$emit('onPageChange', this.pagination)
        },
        onShowSizeChange: (current, pageSize) => {
          this.pagination.current = 1
          this.pagination.pageSize = pageSize
          this.$emit('onPageChange', this.pagination)
        }
      },
      allSelectRows: [],
      needTotalList: []
    }
  },
  methods: {
    onSelect(record, selected) {
      if (this.multipleSelect) {
        selected ? this.allSelectRows.push(record) : this.allSelectRows.splice(this.allSelectRows.findIndex(item => item.id === record.id), 1)
      }
      else {
        this.onClear()
        selected ? this.allSelectRows.push(record) : this.allSelectRows.splice(this.allSelectRows.findIndex(item => item.id === record.id), 1)
      }
      this.$emit('update:selectedRows', this.allSelectRows)
    },
    onSelectAll(selected, selectedRows, changeRows) {
      this.allSelectRows = selected ? this.allSelectRows.concat(changeRows) : this.allSelectRows.filter(item => !changeRows.find(index => index.id === item.id))
      this.$emit('update:selectedRows', this.allSelectRows)
    },
    onSelectChange (selectedRowKeys, selectedRows) {
      this.$emit('update:selectedRows', selectedRows)
      this.$emit('selectedRowChange', selectedRowKeys, selectedRows)
    },
    initTotalList (columns) {
      const totalList = columns.filter(item => item.needTotal)
        .map(item => {
          return {
            ...item,
            total: 0
          }
        })
      return totalList
    },
    onClear() {
      this.allSelectRows = []
      this.onSelectChange([], [])
      this.$emit('update:selectedRows', this.allSelectRows)
      this.$emit('clear')
    }
  },
  created () {
    this.needTotalList = this.initTotalList(this.columns)
  },
  watch: {
    selectedRows (selectedRows) {
      this.allSelectRows = selectedRows
      this.needTotalList = this.needTotalList.map(item => {
        return {
          ...item,
          total: selectedRows.reduce((sum, val) => {
            let v
            try{
              v = val[item.dataIndex] ? val[item.dataIndex] : eval(`val.${item.dataIndex}`);
            }catch(_){
              v = val[item.dataIndex];
            }
            v = !isNaN(parseFloat(v)) ? parseFloat(v) : 0;
            return sum + v
          }, 0)
        }
      })
    },
    page(val) {
      this.pagination.current = val
    },
    total(val) {
      this.pagination.total = val
    }
  },
  computed: {
    selectedRowKeys() {
      return this.allSelectRows.map(record => {
        return (typeof this.rowKey === 'function') ? this.rowKey(record) : record[this.rowKey]
      })
    },
    getPagination() {
      return this.isPagination ? this.pagination : false
    }
  }
}
</script>

<style scoped lang="less">
  .standard-table{
    .alert{
      margin-bottom: 16px;
      .message{
        a{
          font-weight: 600;
        }
      }
      .clear{
        float: right;
      }
    }
  }
  /deep/.table-striped {
    background-color: #fafafa;
  }
  /deep/.ant-table-body {
    overflow-x: auto !important;
  }
  /deep/.ant-table-tbody > tr.ant-table-row-selected td {
    background-color: @primary-1;
  }
  /deep/.ant-table td { 
    white-space: nowrap;
  }
</style>
